package com.itheima.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.itheima.entity.User;
import com.itheima.exception.BusinessException;
import com.itheima.exception.LoginException;
import com.itheima.mapper.UserMapper;
import com.itheima.service.UserService;
import com.itheima.template.JWTTemplate;
import com.itheima.template.SMSTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.Map;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private SMSTemplate smsTemplate;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private JWTTemplate jwtTemplate;

    @Override
    public void sendSms(String telephone) {
        //1.生成随机验证码
        String code = RandomUtil.randomNumbers(4);

        //2.开发中我们直接将验证码存入redis中
        redisTemplate.opsForValue().set("LOGIN_CODE:"+telephone,code, Duration.ofMinutes(5));
        System.out.println(code);

        /*try {
            //2.调用smsTemplate发送短信
            SendSmsResponse sendSmsResponse = smsTemplate.sendSms(telephone, code);

            //3.判断发送是否成功
            if ("ok".equalsIgnoreCase(sendSmsResponse.getCode())) {
                //3.1若成功,将验证码存入redis中,且设置时效5分钟
                redisTemplate.opsForValue().set("LOGIN_CODE:"+telephone,code, Duration.ofMinutes(5));
            }else {
                //3.2若失败,通过抛异常的方式提示用户
                throw new BusinessException(sendSmsResponse.getMessage());
            }
        } catch (ClientException e) {
            e.printStackTrace();
            throw new BusinessException("短信发送失败,请稍后再试");
        }*/
    }

    @Override
    public String login(Map<String, String> paramMap) {
        //1.先获取参数手机号和验证码
        String telephone = paramMap.get("telephone");
        String code = paramMap.get("code");

        //2.参数校验
        if (StrUtil.isBlank(telephone) || StrUtil.isBlank(code)) {
            throw new BusinessException("手机号和验证码不能为空");
        }

        //3.获取redis中的验证码
        Object redisCode = redisTemplate.opsForValue().get("LOGIN_CODE:" + telephone);

        //3.1判断redis中的验证码时候存在,若不存在抛异常
        if (redisCode == null) {
            throw new BusinessException("请先发送验证码");
        }

        //4.判断用户输入的验证码是否正确,若不正确抛异常
        if (!StrUtil.equals(redisCode.toString(),code)) {
            throw new BusinessException("请输入正确的验证码");
        }

        //5.调用userMapper中方法判断用户是否存在,若不存在抛异常
        User user = userMapper.findByTelephone(telephone);
        if (user == null) {
            throw new BusinessException("此用户无权访问后台系统");
        }

        //6.若都没有问题,需要生成一个token,将token写回浏览器
        //6.1 将用户的一些核心数据去除
        user.setPassword(null);
        user.setTelephone(null);

        //6.2 创建map集合,存放用户的数据(建议使用hutool)
        Map<String, Object> map = BeanUtil.beanToMap(user);

        //6.3 调用模板类生成token
        String token = jwtTemplate.createJWT(map);
        return token;
    }

    @Override
    public void verify(String token) {
        try {
            jwtTemplate.parseJWT(token);
        } catch (Exception e) {
            e.printStackTrace();
            throw new LoginException();
        }
    }
}
